﻿
using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExcelWordToHtml
{
	public static class HtmlHelper
	{
		private static readonly List<KeyValuePair<HorizontalAlignment, string>> HALIGN = new List<KeyValuePair<HorizontalAlignment, string>>
	{
		new KeyValuePair<HorizontalAlignment, string>(HorizontalAlignment.Left, "left"),
		new KeyValuePair<HorizontalAlignment, string>(HorizontalAlignment.Center, "center"),
		new KeyValuePair<HorizontalAlignment, string>(HorizontalAlignment.Right, "right"),
		new KeyValuePair<HorizontalAlignment, string>(HorizontalAlignment.Fill, "left"),
		new KeyValuePair<HorizontalAlignment, string>(HorizontalAlignment.Justify, "left"),
		new KeyValuePair<HorizontalAlignment, string>(HorizontalAlignment.CenterSelection, "center")
	};

		private static readonly List<KeyValuePair<VerticalAlignment, string>> VALIGN = new List<KeyValuePair<VerticalAlignment, string>>
	{
		new KeyValuePair<VerticalAlignment, string>(VerticalAlignment.Bottom, "bottom"),
		new KeyValuePair<VerticalAlignment, string>(VerticalAlignment.Center, "middle"),
		new KeyValuePair<VerticalAlignment, string>(VerticalAlignment.Top, "top")
	};

		private static readonly List<KeyValuePair<BorderStyle, string>> BORDER = new List<KeyValuePair<BorderStyle, string>>
	{
		new KeyValuePair<BorderStyle, string>(BorderStyle.DashDot, "dashed 1pt"),
		new KeyValuePair<BorderStyle, string>(BorderStyle.DashDotDot, "dashed 1pt"),
		new KeyValuePair<BorderStyle, string>(BorderStyle.Dashed, "dashed 1pt"),
		new KeyValuePair<BorderStyle, string>(BorderStyle.Dotted, "dotted 1pt"),
		new KeyValuePair<BorderStyle, string>(BorderStyle.Double, "double 3pt"),
		new KeyValuePair<BorderStyle, string>(BorderStyle.Hair, "dashed 1px"),
		new KeyValuePair<BorderStyle, string>(BorderStyle.Medium, "solid 2pt"),
		new KeyValuePair<BorderStyle, string>(BorderStyle.MediumDashDot, "dashed 2pt"),
		new KeyValuePair<BorderStyle, string>(BorderStyle.MediumDashDotDot, "dashed 2pt"),
		new KeyValuePair<BorderStyle, string>(BorderStyle.MediumDashed, "dashed 2pt"),
		new KeyValuePair<BorderStyle, string>(BorderStyle.None, "none"),
		new KeyValuePair<BorderStyle, string>(BorderStyle.SlantedDashDot, "dashed 2pt"),
		new KeyValuePair<BorderStyle, string>(BorderStyle.Thick, "solid 3pt"),
		new KeyValuePair<BorderStyle, string>(BorderStyle.Thin, "solid 1pt")
	};

		public static string GetExcelHtml(IEnumerable<ExcelSheetModel> sheetList)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			StringBuilder sb = new StringBuilder();
			add("<!DOCTYPE html>");
			add("<html lang=\"zh-CN\">");
			add("<head>");
			add("    <meta name=\"renderer\" content=\"webkit|ie-comp|ie-stand\" />");
			add("    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />");
			add("    <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">");
			add("    <meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1,IE=edge\">");
			add("    <title>EXCEl预览</title>");
			add("    <style>");
			add("        html,body,.sheet-content{");
			add("            position: relative;");
			add("            height: 100%;");
			add("            width: 100%;");
			add("            -moz-box-sizing: border-box;");
			add("            -webkit-box-sizing: border-box;");
			add("            box-sizing: border-box;");
			add("            margin: 0;");
			add("            padding: 0;");
			add("            overflow: hidden;");
			add("        }");
			add("        .sheet-bar{");
			add("            -moz-box-sizing: border-box;");
			add("            -webkit-box-sizing: border-box;");
			add("            box-sizing: border-box;");
			add("            position:absolute;");
			add("            bottom: 0;");
			add("            left: 0;");
			add("            border-top: 1px solid #ccc;");
			add("            height: 32px;");
			add("            width: 100%;");
			add("            font-size: 0;");
			add("            white-space:nowrap;");
			add("            overflow-x: auto;");
			add("            overflow-y: hidden;");
			add("        }");
			add("        .sheet-bar-item{");
			add("            -moz-box-sizing: border-box;");
			add("            -webkit-box-sizing: border-box;");
			add("            box-sizing: border-box;");
			add("            position: relative;");
			add("            display: inline-block;");
			add("            font-size: 14px;");
			add("            height: 32px;");
			add("            line-height: 32px;");
			add("            padding: 0 16px;");
			add("            border-right:1px solid #ccc;");
			add("            background-color: #f2f2f2;");
			add("            cursor: pointer;");
			add("            color: #666;");
			add("        }");
			add("        .sheet-bar-item.active{");
			add("            background-color: #fff;");
			add("            color: #04BCC1;");
			add("        }");
			add("        .sheet-bar-item.active:after {");
			add("            position: absolute;");
			add("            left: 0;");
			add("            bottom: 0;");
			add("            content: '';");
			add("            width: 100%;");
			add("            height: 4px;");
			add("            box-sizing: border-box;");
			add("            pointer-events: none;");
			add("            border-bottom: 4px solid #04BCC1;");
			add("        }");
			add("        .sheet-content-item{");
			add("            position: relative;");
			add("            height: 100%;");
			add("            width: 100%;");
			add("            -moz-box-sizing: border-box;");
			add("            -webkit-box-sizing: border-box;");
			add("            box-sizing: border-box;");
			add("            overflow: auto;");
			add("            display: none;");
			add("        }");
			add("        .sheet-content-item.show{");
			add("            display: block;");
			add("        }");
			add("        td{");
			add("            height: 13.5pt;");
			add("            font-size: 11pt;");
			add("            white-space: pre;");
			add("            color:#000;");
			add("        }");
			add("        .ftr>td{");
			add("            height: 0;");
			add("        }");
			add("        .right{");
			add("            text-align: right;");
			add("        }");
			add("        .center{");
			add("            text-align: center;");
			add("        }");
			add("{$style}");
			add("    </style>");
			add("</head>");
			add("<body style=\"padding-bottom: 32px;\" >");
			add("    <div class=\"sheet-content\" >");
			string text = "";
			int num = 0;
			foreach (ExcelSheetModel sheet in sheetList)
			{
				text += "<div class=\"sheet-bar-item";
				if (num == 0)
				{
					text += " active ";
				}
				text = text + "\" data-value=\"" + sheet.Id + "\"  >" + sheet.Name + "</div>";
				add("        <div class=\"sheet-content-item " + ((num == 0) ? "show" : "") + " \" id =\"" + sheet.Id + "\" >" + GetSheetHtml(sheet, dictionary) + "</div>");
				num++;
			}
			add("    </div>");
			add("    <div class=\"sheet-bar\" >");
			add("        " + text);
			add("    </div>");
			add("    <script>");
			add("        window.onload = function(){");
			add("            var btnlist = document.querySelectorAll('.sheet-bar-item');");
			add("            for(var i = 0,l =btnlist.length;i<l;i++){");
			add("                btnlist[i].onclick=function () {");
			add("                    var sheetId = this.getAttribute('data-value');");
			add("                    if(this.className.indexOf('active') == -1){");
			add("                        document.getElementsByClassName('active')[0].className = 'sheet-bar-item';");
			add("                        this.className = 'sheet-bar-item active';");
			add("                        document.getElementsByClassName('show')[0].className = 'sheet-content-item';");
			add("                        document.getElementById(sheetId).className = 'sheet-content-item show';");
			add("                    }");
			add("                }");
			add("            }");
			add("        }");
			add("    </script>");
			add("</body>");
			add("</html>");
			string text2 = "";
			foreach (KeyValuePair<string, string> item in dictionary)
			{
				text2 = text2 + "        ." + item.Value + "{" + item.Key + "}\r\n";
			}
			string text3 = sb.ToString();
			return text3.Replace("{$style}", text2);
			void add(string str)
			{
				sb.Append(str + "\r\n");
			}
		}

		public static string GetSheetHtml(ExcelSheetModel sheet, Dictionary<string, string> classMap)
		{
			StringBuilder sb = new StringBuilder();
			add("<table cellspacing=\"0\" cellpadding=\"0\" style=\"border-collapse:collapse;table-layout:fixed;width:" + sheet.TableWidth + "px;\"  >");
			add("<tr class=\"ftr\">");
			foreach (decimal cellWidth in sheet.CellWidths)
			{
				add("<td style=\"" + GetPXStyle("width", cellWidth) + "\"></td>");
			}
			add("</tr>");
			foreach (ExcelRowModel row in sheet.Rows)
			{
				add("<tr>");
				foreach (ExcelCellModel cell in row.Cells)
				{
					string style = GetStyle(cell);
					string text = "";
					if (!string.IsNullOrEmpty(style))
					{
						string text2 = "c" + classMap.Count;
						if (classMap.ContainsKey(style))
						{
							text2 = classMap[style];
						}
						else
						{
							classMap.Add(style, text2);
						}
						text = "class=\"" + text2 + "\"";
					}
					add(string.Format("<td {0}{1}{2}>{3}</td>", text, GetRowColSpan("rowspan", cell.RowSpan), GetRowColSpan("colspan", cell.ColumnSpan), cell.Text));
				}
				add("</tr>");
			}
			add("</table>");
			return sb.ToString();
			void add(string str)
			{
				sb.Append(str + "\r\n");
			}
		}

		private static string GetRowColSpan(string type, int span)
		{
			if (span == 1)
			{
				return "";
			}
			return $" {type}=\"{span}\"";
		}

		private static string GetPXStyle(string k, decimal w)
		{
			return k + ":" + w + "px;";
		}

		private static string StyleOut(string k, HorizontalAlignment p, CellType cellType)
		{
			if (p == HorizontalAlignment.General)
			{
				string text = "";
				switch (cellType)
				{
					case CellType.Boolean:
					case CellType.Error:
						text = "text-align:center;";
						break;
					case CellType.Numeric:
						text = "text-align:right;";
						break;
					default:
						text = "";
						break;
				}
				return text;
			}
			return k + ":" + HALIGN.Where((KeyValuePair<HorizontalAlignment, string> o) => o.Key == p).First().Value + ";";
		}

		private static string StyleOut(string k, VerticalAlignment p)
		{
			return k + ":" + VALIGN.Where((KeyValuePair<VerticalAlignment, string> o) => o.Key == p).First().Value + ";";
		}

		private static string StyleOut(string k, BorderStyle p, string color)
		{
			if (p == BorderStyle.None)
			{
				return "";
			}
			string text = k + ":" + BORDER.Where((KeyValuePair<BorderStyle, string> o) => o.Key == p).First().Value;
			if (!string.IsNullOrEmpty(color))
			{
				text = text + " " + color;
			}
			return text + ";";
		}

		private static string StyleOut(bool isWrapText)
		{
			if (isWrapText)
			{
				return "white-space:pre-wrap;";
			}
			return "";
		}

		private static string SetHeight(float h)
		{
			if (h == 0f)
			{
				return "";
			}
			return "height:" + h + "pt;";
		}

		private static string SetFontWeight(short w, bool isBold)
		{
			if (isBold)
			{
				return "font-weight:bold;";
			}
			if (w == 400)
			{
				return "";
			}
			return "font-weight:" + w + ";";
		}

		private static string SetFontSize(double size)
		{
			if (size == 11.0)
			{
				return "";
			}
			return "font-size:" + size + "pt;";
		}

		private static string SetFontItalic(bool isItalic)
		{
			if (isItalic)
			{
				return "font-style:italic;";
			}
			return "";
		}

		private static string SetFontFamily(string FontName)
		{
			if (!string.IsNullOrEmpty(FontName))
			{
				return "font-family:" + FontName + ";";
			}
			return "";
		}

		private static string SetFillColor(string color)
		{
			if (!string.IsNullOrEmpty(color))
			{
				return "background-color:" + color + ";";
			}
			return "";
		}

		private static string SetFontColor(string color)
		{
			if (string.IsNullOrEmpty(color) || color == "#000000")
			{
				return "";
			}
			return "color:" + color + ";";
		}

		private static string GetStyle(ExcelCellModel cell)
		{
			string text = "";
			text += StyleOut("text-align", cell.Alignment, cell.CellType);
			text += StyleOut("vertical-align", cell.VerticalAlignment);
			text += StyleOut("border-left", cell.BorderLeft, cell.BorderLeftColor);
			text += StyleOut("border-right", cell.BorderRight, cell.BorderRightColor);
			text += StyleOut("border-top", cell.BorderTop, cell.BorderTopColor);
			text += StyleOut("border-bottom", cell.BorderBottom, cell.BorderBottomColor);
			text += StyleOut(cell.WrapText);
			text += SetHeight(cell.HeightInPoints);
			if (cell.Font != null)
			{
				text += SetFontWeight(cell.Font.Boldweight, cell.Font.IsBold);
				text += SetFontSize(cell.Font.FontHeightInPoints);
				text += SetFontItalic(cell.Font.IsItalic);
				text += SetFontFamily(cell.Font.FontName);
			}
			text += SetFillColor(cell.FillColor);
			return text + SetFontColor(cell.FontColor);
		}
	}
}
